#pragma once
#include "pch.h"
#include "Direct3DApplication.h"


void Direct3DApplication::Initialize(CoreWindow^ window)
{
	coreWindow = window;
}

void Direct3DApplication::CreateDeviceAndSwapChain()
{
	UINT deviceCreationFlags = D3D11_CREATE_DEVICE_BGRA_SUPPORT;
	//If debug add |= D3D11_CREATE_DEVICE_DEBUG;

	D3D_FEATURE_LEVEL* featureLevel = nullptr;
	ComPtr<ID3D11Device> tmpDevice;
	ComPtr<ID3D11DeviceContext> tmpContext;

	D3D11CreateDevice(
		nullptr,
		D3D_DRIVER_TYPE_HARDWARE,
		nullptr,
		deviceCreationFlags,
		nullptr,
		0,
		D3D11_SDK_VERSION,
		&tmpDevice,
		featureLevel,
		&tmpContext);

	tmpDevice.As(&d3dDevice);
	tmpContext.As(&d3dContext);

	//Create the swap chain:
	DXGI_SWAP_CHAIN_DESC1 scDesc = {0};

	Rect windowBounds = this->coreWindow->Bounds;
	Size windowSize;

	windowSize.Width = windowBounds.Width;
	windowSize.Height = windowBounds.Height;

	scDesc.Width = static_cast<UINT>(windowSize.Width);
	scDesc.Height = static_cast<UINT>(windowSize.Height);

	scDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
	scDesc.Stereo = false;
	scDesc.SampleDesc.Count = 1;
	scDesc.SampleDesc.Quality = 0;
	scDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
	scDesc.BufferCount = 2;
	scDesc.Scaling = DXGI_SCALING_NONE;
	scDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL;
	scDesc.Flags = 0;

	ComPtr<IDXGIDevice1> dxgiDevice;
	d3dDevice.As(&dxgiDevice);
	ComPtr<IDXGIAdapter> dxgiAdapter;
	dxgiDevice->GetAdapter(&dxgiAdapter);
	ComPtr<IDXGIFactory2> dxgiFactory;
	dxgiAdapter->GetParent(__uuidof(IDXGIFactory2), &dxgiFactory);
	
	dxgiFactory->CreateSwapChainForCoreWindow(
		d3dDevice.Get(),
		reinterpret_cast<IUnknown*>(coreWindow),
		&scDesc,
		nullptr, //Not needed for now.
		&dxgiSwapChain);



}

Direct3DApplication::Direct3DApplication()
{
	Initialize(CoreWindow::GetForCurrentThread());

	CreateDeviceAndSwapChain();
	CreateDeviceIndependantResources();
	CreateDeviceDependantResources();
}

void Direct3DApplication::CreateDeviceIndependantResources()
{
	D2D1_FACTORY_OPTIONS factoryOptions;
	factoryOptions.debugLevel = D2D1_DEBUG_LEVEL_NONE;

	ComPtr<ID2D1Factory> tmpFactory;

	D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, __uuidof(ID2D1Factory), &factoryOptions, &tmpFactory);

	tmpFactory.As(&d2dFactory);

}

void Direct3DApplication::CreateDeviceDependantResources()
{
	ComPtr<IDXGIDevice1> dxgiDevice;
	d3dDevice.As(&dxgiDevice);

	//D2D1_SIZE_U size = D2D1::Size(
	//	static_cast<UINT>(coreWindow->Bounds.Width),
	//	static_cast<UINT>(coreWindow->Bounds.Height)
	//	);

	
	//dxgiSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), &backBuffer);

	//d3dDevice->CreateRenderTargetView(backBuffer.Get(), nullptr, &d3dRenderTargetView);

	d2dFactory->CreateDevice(dxgiDevice.Get(), &d2dDevice);
	d2dDevice->CreateDeviceContext(D2D1_DEVICE_CONTEXT_OPTIONS_NONE, &d2dDeviceContext);

	ComPtr<IDXGISurface> dxgiBackBuffer;
	dxgiSwapChain->GetBuffer(0, IID_PPV_ARGS(&dxgiBackBuffer));

	D2D1_BITMAP_PROPERTIES1 bitmapProperties = D2D1::BitmapProperties1(
		D2D1_BITMAP_OPTIONS_TARGET | D2D1_BITMAP_OPTIONS_CANNOT_DRAW,
		D2D1::PixelFormat(DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_PREMULTIPLIED),
		96, 96);

	ComPtr<ID2D1Bitmap1> d2dTarget;
	d2dDeviceContext->CreateBitmapFromDxgiSurface(dxgiBackBuffer.Get(), &bitmapProperties, &d2dTarget);

	d2dDeviceContext->SetTarget(d2dTarget.Get());

	d2dDeviceContext->CreateSolidColorBrush(D2D1::ColorF(D2D1::ColorF::White), &scbWhite);
}